/**
 *
 * © Bahadir Zeren 2011
 * bzeren@gmail.com
 * No warranties, express or implied, are made for this program.
 *
 */

package org.baatar.opt.genetic.selection;

import java.util.ArrayList;
import java.util.Comparator;
import org.baatar.opt.genetic.chromosome.IChromosome;
import org.baatar.util.RandomUtil;

/**
 * Binary tournament selection implementation of the ISelection interface.
 * 
 * @see ISelection
 */
public class BinaryTournamentSelection<T> implements ISelection<T> {

    /**
     * {@inheritDoc}
     */
    @Override
    public IChromosome<T> selectChromosomeForReproduction(IChromosome<T>[] population,
                                                            Comparator<IChromosome<T>> comparator) {

        IChromosome<T> c1 = population[RandomUtil.getRandNumber(population.length)];
        IChromosome<T> c2 = population[RandomUtil.getRandNumber(population.length)];

        while ((c1 == c2) || c1.isEqual(c2))
            c2 = population[RandomUtil.getRandNumber(population.length)];

        if (comparator.compare(c1, c2) > 0)
            return c1;
        else
            return c2;

    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Integer selectChromosomeIndexForSurvival(ArrayList<IChromosome<T>> chromosomeList,
                                                            Comparator<IChromosome<T>> comparator) {

        if (chromosomeList.size() == 1)
            return 0;

        int firstCandidateIndex = RandomUtil.getRandNumber(chromosomeList.size());
        IChromosome<T> c1 = chromosomeList.get(firstCandidateIndex);

        int secondCandidateIndex = RandomUtil.getRandNumber(chromosomeList.size());
        while (firstCandidateIndex == secondCandidateIndex) {
            secondCandidateIndex = RandomUtil.getRandNumber(chromosomeList.size());
        }
        IChromosome<T> c2 = chromosomeList.get(secondCandidateIndex);

        if (comparator.compare(c1, c2) > 0)
            return firstCandidateIndex;
        else
            return secondCandidateIndex;

    }
}
